package com.ybear.ybcomponent.clicksub;

import android.view.View;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 点击订阅管理器
 */
public final class ClickSubManage implements ClickSubDao {
    private final Map<Integer, List<View.OnClickListener>> mClickMap;
    private final Map<Integer, List<View.OnLongClickListener>> mLongClickMap;

    private ClickSubManage() {
        mClickMap = new HashMap<>();
        mLongClickMap = new HashMap<>();
    }

    public static ClickSubManage get() { return HANDLER.I; }
    private static final class HANDLER {
        private static final ClickSubManage I = new ClickSubManage();
    }

    /**
     * 处理点击事件
     * @param v     处理的View
     */
    public void addOnClick(View v) {
        if( v == null ) return;
        enableClick( v );
        mClickMap.put( v.hashCode(), new ArrayList<>() );

        v.setOnClickListener(v1 -> {
            if( !containsClick( v1 ) ) return;
            List<View.OnClickListener> list = mClickMap.get( v1.hashCode() );
            if( list == null ) return;
            try {
                for( View.OnClickListener l : list ) {
                    if( l != null ) l.onClick( v1 );
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 处理长按事件
     * @param v      处理的View
     * @param ret       长按的返回结果
     */
    public void addOnLongClick(View v, boolean ret) {
        if( v == null ) return;
        enableClick( v );
        mLongClickMap.put( v.hashCode(), new ArrayList<>() );

        v.setOnLongClickListener(v1 -> {
            if( !containsLongClick( v1 ) ) return ret;
            List<View.OnLongClickListener> list = mLongClickMap.get( v1.hashCode() );
            if( list == null ) return ret;
            try {
                for( View.OnLongClickListener l : list ) {
                    if( l != null ) l.onLongClick( v1 );
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return ret;
        });
    }

    /**
     * 处理长按事件
     * @param v     处理的View
     */
    public void addOnLongClick(View v) { addOnLongClick( v, false ); }

    private void enableClick(View v) {
        v.setFocusable( true );
        v.setClickable( true );
    }

    /**
     * 点击监听器是否存在
     * @param v     处理事件的View
     * @param l     监听器
     * @return      是否存在
     */
    @Override
    public boolean containsClick(View v, View.OnClickListener l) {
        if( v == null || l == null ) return false;
        int key = v.hashCode();
        List<View.OnClickListener> list = mClickMap.containsKey( key ) ? mClickMap.get( key ) : null;
        if( list == null || list.size() == 0 ) return false;
        for( View.OnClickListener val : list ) {
            if( val != null && val.equals( l ) ) return true;
        }
        return false;
    }

    /**
     * 点击监听器是否存在
     * @param v     处理事件的View
     * @return      是否存在
     */
    @Override
    public boolean containsClick(View v) {
        int key = v == null ? -1 : v.hashCode();
        return key != -1 && mClickMap.containsKey( key );
    }

    /**
     * 点击监听器是否存在
     * @param l     监听器
     * @return      是否存在
     */
    @Override
    public boolean containsClick(View.OnClickListener l) {
        if( l == null ) return false;
        for( Integer key : mClickMap.keySet() ) {
            List<View.OnClickListener> list = mClickMap.get( key );
            if( list == null || list.size() == 0 ) return false;
            for( View.OnClickListener listener : list ) {
                if( listener != null && listener.equals( l ) ) return true;
            }
        }
        return false;
    }

    /**
     * 添加点击事件监听器
     * @param l     监听器
     */
    @Override
    public void addOnClickListener(View v, View.OnClickListener l) {
        if( l == null ) return;
        if( !containsClick( v ) ) addOnClick( v );
        List<View.OnClickListener> list = mClickMap.get( v.hashCode() );
        if( list == null ) list = new ArrayList<>();
        list.add( l );
        mClickMap.put( v.hashCode(), list );
    }

    /**
     * 移除点击事件监听器
     * @param v     处理事件的View
     * @param l     监听器
     */
    @Override
    public void removeOnClickListener(View v, View.OnClickListener l) {
        if( !containsClick( v ) || l == null ) return;
        List<View.OnClickListener> list = mClickMap.get( v.hashCode() );
        if( list != null && list.size() > 0 ) list.remove( l );
    }

    /**
     * 移除点击事件监听器
     * @param v     处理事件的View
     */
    @Override
    public void removeOnClickListener(View v) {
        if( v == null ) return;
        mClickMap.remove( v.hashCode() );
    }

    /**
     * 移除点击事件监听器
     * @param l     监听器
     */
    @Override
    public void removeOnClickListener(View.OnClickListener l) {
        if( l == null ) return;
        Iterator<Integer> iterator = mClickMap.keySet().iterator();
        while ( iterator.hasNext() ) {
            Integer key = iterator.next();
            List<View.OnClickListener> list = mClickMap.get( key );
            if( list != null && list.size() > 0 ) {
                Iterator<View.OnClickListener> listIterator = list.iterator();
                while( iterator.hasNext() ) {
                    View.OnClickListener listener = listIterator.next();
                    if( listener != null && listener.equals( l ) ) iterator.remove();
                }
            }
            if( list == null || list.size() == 0 ) iterator.remove();
        }
    }

    /**
     * 长按监听器是否存在
     * @param v     处理事件的View
     * @param l     监听器
     * @return      是否存在
     */
    @Override
    public boolean containsLongClick(View v, View.OnLongClickListener l) {
        if( l == null ) return false;
        for (Integer key : mLongClickMap.keySet()) {
            List<View.OnLongClickListener> list = mLongClickMap.get( key );
            if( list == null || list.size() == 0 ) return false;
            for (View.OnLongClickListener listener : list) {
                if( listener != null && listener.equals( l ) ) return true;
            }
        }
        return false;
    }

    /**
     * 长按监听器是否存在
     * @param v     处理事件的View
     * @return      是否存在
     */
    @Override
    public boolean containsLongClick(View v) {
        int key = v == null ? -1 : v.hashCode();
        return key != -1 && mLongClickMap.containsKey( key );
    }

    /**
     * 长按监听器是否存在
     * @param l     监听器
     * @return      是否存在
     */
    @Override
    public boolean containsLongClick(View.OnLongClickListener l) {
        if( l == null ) return false;
        for (Integer key : mLongClickMap.keySet()) {
            List<View.OnLongClickListener> list = mLongClickMap.get( key );
            if( list == null || list.size() == 0 ) return false;
            for (View.OnLongClickListener listener : list) {
                if( listener != null && listener.equals( l ) ) return true;
            }
        }
        return false;
    }

    /**
     * 添加长按事件监听器
     * @param v     处理事件的View
     * @param l     监听器
     */
    @Override
    public void addOnLongClickListener(View v, View.OnLongClickListener l) {
        if( l == null ) return;
        if( !containsLongClick( v ) ) addOnLongClick( v );
        int key = v.hashCode();
        List<View.OnLongClickListener> list = mLongClickMap.containsKey( key ) ?
                mLongClickMap.get( key ) : null;
        if( list == null ) list = new ArrayList<>();
        list.add( l );
        mLongClickMap.put( key, list );
    }

    /**
     * 移除长按事件监听器
     * @param v     处理事件的View
     * @param l     监听器
     */
    @Override
    public void removeOnLongClickListener(View v, View.OnLongClickListener l) {
        if( l == null || !containsLongClick( v ) ) return;
        int key = v.hashCode();
        List<View.OnLongClickListener> list = mLongClickMap.get( key );
        if( list != null && list.size() > 0 ) list.remove( l );
        if( list == null || list.size() == 0 ) mLongClickMap.remove( key );
    }

    /**
     * 移除长按事件监听器
     * @param v     处理事件的View
     */
    @Override
    public void removeOnLongClickListener(View v) {
        if( v == null ) return;
        mLongClickMap.remove( v.hashCode() );
    }

    /**
     * 移除长按事件监听器
     * @param l     监听器
     */
    @Override
    public void removeOnLongClickListener(View.OnLongClickListener l) {
        if( l == null ) return;
        Iterator<Integer> iterator = mLongClickMap.keySet().iterator();
        while ( iterator.hasNext() ) {
            Integer key = iterator.next();
            List<View.OnLongClickListener> list = mLongClickMap.get( key );
            if( list != null && list.size() > 0 ) {
                Iterator<View.OnLongClickListener> listIterator = list.iterator();
                while( iterator.hasNext() ) {
                    View.OnLongClickListener listener = listIterator.next();
                    if( listener != null && listener.equals( l ) ) iterator.remove();
                }
            }
            if( list == null || list.size() == 0 ) iterator.remove();
        }
    }
}
